package follow_interface;

import jasona.Services;

import java.io.IOException;
import java.util.ArrayList;

import myutil.GetTable;

import org.apache.hadoop.hbase.client.Delete;
import org.apache.hadoop.hbase.client.Get;
import org.apache.hadoop.hbase.client.HTable;
import org.apache.hadoop.hbase.client.Put;
import org.apache.hadoop.hbase.client.Result;
import org.apache.hadoop.hbase.client.ResultScanner;
import org.apache.hadoop.hbase.client.Scan;
import org.apache.hadoop.hbase.util.Bytes;

import user_interface.User;

public class Follow {
	public static boolean base_follow(String username, String busername) {
		if (User.checkUsername(username) || User.checkUsername(busername)) {
			return false;
		} else {
			GetTable gt = new GetTable("follow");
			HTable ht = gt.ht;
			byte[] rowid = Bytes.toBytes(username + "$" + busername);
			byte[] family = Bytes.toBytes("mutual");
			Put put = new Put(rowid).add(family, Bytes.toBytes("dc"),
					Bytes.toBytes(""));
			try {
				ht.put(put);
				return true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			} finally {
				gt.CloseTable();
			}
		}
	}

	public static boolean base_bfollow(String username, String busername) {
		if (User.checkUsername(username) || User.checkUsername(busername)) {
			return false;
		} else {
			GetTable gt = new GetTable("bfollow");
			HTable ht = gt.ht;
			byte[] rowid = Bytes.toBytes(busername + "$" + username);
			byte[] family = Bytes.toBytes("empty");
			Put put = new Put(rowid).add(family, Bytes.toBytes("dc"),
					Bytes.toBytes(""));
			try {
				ht.put(put);
				return true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			} finally {
				gt.CloseTable();
			}
		}
	}

	public static boolean follow(String username, String busername) {
		return base_follow(username, busername)
				&& base_bfollow(username, busername);
	}

	public static boolean base_unfollow(String username, String busername) {
		if (User.checkUsername(username) || User.checkUsername(busername)) {
			return false;
		} else {
			GetTable gt = new GetTable("follow");
			HTable ht = gt.ht;
			byte[] rowid = Bytes.toBytes(username + "$" + busername);
			Delete dl = new Delete(rowid);
			try {
				ht.delete(dl);
				return true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			} finally {
				gt.CloseTable();
			}
		}
	}

	public static boolean base_unbfollow(String username, String busername) {
		if (User.checkUsername(username) || User.checkUsername(busername)) {
			return false;
		} else {
			GetTable gt = new GetTable("bfollow");
			HTable ht = gt.ht;
			byte[] rowid = Bytes.toBytes(busername + "$" + username);
			Delete dl = new Delete(rowid);
			try {
				ht.delete(dl);
				return true;
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return false;
			} finally {
				gt.CloseTable();
			}
		}
	}

	public static boolean unfollow(String username, String busername) {
		return base_unfollow(username, busername)
				&& base_unbfollow(username, busername);
	}

	public static boolean checkFollow(String username, String busername) {
		GetTable gt = new GetTable("follow");
		HTable ht = gt.ht;
		Get g = new Get(Bytes.toBytes(username + "$" + busername));
		try {
			Result r = ht.get(g);
			if (r.size() == 0)
				return false;
			else
				return true;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return false;
		} finally {
			gt.CloseTable();
		}
	}

	public static Services.SimpleUser getInfo(String username) {
		Services.SimpleUser su = new Services.SimpleUser();
		if (User.checkUsername(username))
			return null;
		GetTable gt = new GetTable("userinfo");
		HTable ht = gt.ht;
		Get g = new Get(Bytes.toBytes(username));
		try {
			Result r = ht.get(g);
			su.username = Bytes.toString(r.getValue(Bytes.toBytes("metainfo"),
					Bytes.toBytes("username")));
			su.nickname = Bytes.toString(r.getValue(Bytes.toBytes("metainfo"),
					Bytes.toBytes("nickname")));
			su.email = Bytes.toString(r.getValue(Bytes.toBytes("metainfo"),
					Bytes.toBytes("email")));
			su.type = Bytes.toString(r.getValue(Bytes.toBytes("metainfo"),
					Bytes.toBytes("type")));
			su.head = r.getValue(Bytes.toBytes("metainfo"),
					Bytes.toBytes("head"));
			su.currentweibo = Bytes.toString(r.getValue(
					Bytes.toBytes("metainfo"), Bytes.toBytes("currentweibo")));
			return su;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} finally {
			gt.CloseTable();
		}
	}

	public static ArrayList<Services.SimpleUser> getFollow(String username)// ->username
	{
		GetTable gt = new GetTable("bfollow");
		HTable ht = gt.ht;
		GetTable gt2 = new GetTable("userinfo");
		HTable ht2 = gt2.ht;
		ArrayList<Services.SimpleUser> usersRs = new ArrayList<Services.SimpleUser>();

		// //////////////////////////////////////////////////////////////////////////////////////////////////
		Scan sc = new Scan();
		sc.setStartRow(Bytes.toBytes(username + "#"));
		sc.setStopRow(Bytes.toBytes(username + "~"));
		// ArrayList<byte[]> users = new ArrayList<byte[]>();
		ResultScanner result;
		ArrayList<Get> usergets = new ArrayList<Get>();
		try {
			result = ht.getScanner(sc);
			for (Result r : result) {
				byte[] user = Bytes.toBytes(Bytes.toString(r.getRow()).replace(
						username + "$", ""));
				//System.out.println(Bytes.toString(user));
				usergets.add(new Get(user));
			}
			// todo:get batch
			Result[] rs = ht2.get(usergets);
			for (Result r : rs) {
				Services.SimpleUser sstemp = new Services.SimpleUser();
				sstemp.username = Bytes.toString(r.getRow());
				System.out.println(sstemp.username);
				sstemp.nickname = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("nickname")));
				sstemp.email = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("email")));
				sstemp.type = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("type")));
				sstemp.currentweibo = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("currentweibo")));
				sstemp.head = r.getValue(Bytes.toBytes("metainfo"),
						Bytes.toBytes("head"));
				if(sstemp!=null)
					usersRs.add(sstemp);
			}
			return usersRs;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} finally {
			gt.CloseTable();
			gt2.CloseTable();
		}
	}

	public static ArrayList<Services.SimpleUser> getbFollow(String username)// username<-
	{
		GetTable gt = new GetTable("follow");
		HTable ht = gt.ht;
		GetTable gt2 = new GetTable("userinfo");
		HTable ht2 = gt2.ht;
		ArrayList<Services.SimpleUser> usersRs = new ArrayList<Services.SimpleUser>();

		// //////////////////////////////////////////////////////////////////////////////////////////////////
		Scan sc = new Scan();
		sc.setStartRow(Bytes.toBytes(username + "#"));
		sc.setStopRow(Bytes.toBytes(username + "~"));
		// ArrayList<byte[]> users = new ArrayList<byte[]>();
		ResultScanner result;
		ArrayList<Get> usergets = new ArrayList<Get>();
		try {
			result = ht.getScanner(sc);
			for (Result r : result) {
				byte[] user = Bytes.toBytes(Bytes.toString(r.getRow()).replace(
						username + "$", ""));
				//System.out.println(Bytes.toString(user));
				usergets.add(new Get(user));
			}
			// todo:get batch
			Result[] rs = ht2.get(usergets);
			for (Result r : rs) {
				Services.SimpleUser sstemp = new Services.SimpleUser();
				sstemp.username = Bytes.toString(r.getRow());
				sstemp.nickname = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("nickname")));
				sstemp.email = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("email")));
				sstemp.type = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("type")));
				/////////////////
				sstemp.currentweibo = Bytes.toString(r.getValue(
						Bytes.toBytes("metainfo"), Bytes.toBytes("currentweibo")));

				///////////////				
				sstemp.head = r.getValue(Bytes.toBytes("metainfo"),
						Bytes.toBytes("head"));
				usersRs.add(sstemp);
			}
			return usersRs;
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			return null;
		} finally {
			gt.CloseTable();
			gt2.CloseTable();
		}
	}
	
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		//System.out.println(Follow.follow("liutaojason", "lyl"));
		//System.out.println(Follow.follow("liutaojason2", "liutaojason2"));
		//System.out.println(Follow.checkFollow("liutaojason", "liutaojason3"));
		//System.out.println(Follow.unfollow("liutaojason", "liutaojason2"));
		//System.out.println(Follow.checkFollow("liutaojason", "liutaojason2"));
		System.out.print(Follow.getbFollow("lyl").size());
		for(Services.SimpleUser ss:Follow.getbFollow("lyl") )
		{
			System.out.println(ss.username);
		}
	}

}
